home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / MNetsrc.hqx / Mac TCP_IP Source v.33 / fingcli.c < prev    next >
Text File  |  1989-02-27  |  6KB  |  276 lines

  1. /*
  2.  *
  3.  *    Finger support...
  4.  *
  5.  *    Finger client routines.  Written by Michael T. Horne - KA7AXD.
  6.  *    Copyright 1988 by Michael T. Horne, All Rights Reserved.
  7.  *    Permission granted for non-commercial use and copying, provided
  8.  *    that this notice is retained.
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "global.h"
  14. #include "config.h"
  15. #include "mbuf.h"
  16. #include "icmp.h"
  17. #include "netuser.h"
  18. #include "timer.h"
  19. #include "tcp.h"
  20. #include "finger.h"
  21. #include "session.h"
  22.  
  23. extern char    badhost[],
  24.         hostname[];
  25.  
  26. /*
  27.  *
  28.  *    Open up a socket to a remote (or the local) host on its finger port.
  29.  *
  30.  */
  31.  
  32. int
  33. dofinger(argc,argv)
  34. int    argc;
  35. char    *argv[];
  36. {
  37.     void        f_state(),
  38.             fingcli_rcv();
  39.     char        *inet_ntoa();
  40.     int32        resolve();
  41.     struct session    *s;
  42.     struct tcb    *tcb;
  43.     struct socket    lsocket,
  44.             fsocket;
  45.     struct finger    *finger,
  46.                     *alloc_finger();
  47.     char        *host;
  48.  
  49.     if (argc < 2) {
  50.         printf("usage: %s [user | user@host | @host]\n", argv[0]);
  51.         return(1);
  52.     }
  53.  
  54.     lsocket.address = ip_addr;
  55.     lsocket.port = lport++;
  56.  
  57. /*
  58.  *    Extract user/host information.  It can be of the form:
  59.  *    
  60.  *    finger user,            # finger local user
  61.  *    finger user@host,        # finger remote user
  62.  *    finger @host            # finger host (give system status)
  63.  *
  64.  */
  65.     if ((finger = alloc_finger()) == NULLFING)
  66.         return(1);
  67.  
  68.     if ((host = index(argv[1], '@')) == NULL) {
  69.         fsocket.address = ip_addr;    /* no host, use local */
  70.         if ((finger->user = malloc(strlen(argv[1]) + 3)) == NULL) {
  71.             free_finger(finger);
  72.             return(1);
  73.         }
  74.         strcpy(finger->user, argv[1]);
  75.         strcat(finger->user, "\015\012");
  76.     }
  77.     else {
  78.         *host++ = '\0';        /* null terminate user name */
  79.         if (*host == '\0') {    /* must specify host */
  80.             printf("%s: no host specified\n", argv[0]);
  81.             printf("usage: %s [user | user@host | @host]\n",
  82.                 argv[0]);
  83.             free_finger(finger);
  84.             return(1);
  85.         }
  86.         if ((fsocket.address = resolve(host)) == 0) {
  87.             printf("%s: ", argv[0]);
  88.             printf(badhost, host); 
  89.             free_finger(finger);
  90.             return(1);
  91.         }
  92.         if ((finger->user = malloc(strlen(argv[1])+3))==NULL) {
  93.             free_finger(finger);
  94.             return 1;
  95.         }
  96.         strcpy(finger->user, argv[1]);
  97.         strcat(finger->user, "\015\012");
  98.     }
  99.     
  100.     fsocket.port = FINGER_PORT;        /* use finger wnp */
  101.  
  102.     /* Allocate a session descriptor */
  103.     if ((s = newsession()) == NULLSESSION){
  104.         printf("Too many sessions\n");
  105.         free_finger(finger);
  106.         return 1;
  107.     }
  108.     current = s;
  109.     s->cb.finger = finger;
  110.     finger->session = s;
  111.  
  112.     if (!host)                /* if no host specified */
  113.         host = hostname;        /* use local host name */
  114.     if ((s->name = malloc(strlen(host)+1)) != NULLCHAR)
  115.         strcpy(s->name, host);
  116.  
  117.     s->type = FINGER;
  118.     s->parse = (int (*)()) NULL;
  119.  
  120.     tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
  121.      fingcli_rcv, (void (*)()) 0, f_state, 0, (int *) finger);
  122.  
  123.     finger->tcb = tcb;
  124.     tcb->user = (char *)finger;
  125.     go();
  126.     return 0;
  127. }
  128.  
  129. /*
  130.  *    Allocate a finger structure for the new session
  131.  */
  132. struct finger *
  133. alloc_finger()
  134. {
  135.     struct finger *tmp;
  136.  
  137.     if ((tmp = (struct finger *) malloc(sizeof(struct finger))) == NULLFING)
  138.         return(NULLFING);
  139.     tmp->session = NULLSESSION;
  140.     tmp->user = (char *) NULL;
  141.     return(tmp);
  142. }
  143.  
  144. /*
  145.  *    Free a finger structure
  146.  */
  147. int
  148. free_finger(finger)
  149. struct finger *finger;
  150. {
  151.     if (finger != NULLFING) {
  152.         if (finger->session != NULLSESSION)
  153.             freesession(finger->session);
  154.         if (finger->user != (char *) NULL)
  155.             free(finger->user);
  156.         free(finger);
  157.     }
  158.     return 0;
  159. }
  160.  
  161. /* Finger receiver upcall routine */
  162. void
  163. fingcli_rcv(tcb, cnt)
  164. register struct tcb    *tcb;
  165. int16            cnt;
  166. {
  167.     struct mbuf    *bp;
  168.     char        *buf;
  169.  
  170.     /* Make sure it's a valid finger session */
  171.     if ((struct finger *) tcb->user == NULLFING) {
  172.         return;
  173.     }
  174.  
  175.     /* Hold output if we're not the current session */
  176.     if (mode != CONV_MODE || current == NULLSESSION
  177.         || current->type != FINGER)
  178.         return;
  179.  
  180.     /*
  181.      *    We process the incoming data stream and make sure it
  182.      *    meets our requirments.  A check is made for control-Zs
  183.      *    since these characters lock up DoubleDos when sent to
  184.      *    the console (don't you just love it...).
  185.      */
  186.  
  187.     if (recv_tcp(tcb, &bp, cnt) > 0)
  188.         while (bp != NULLBUF) {
  189.             buf = bp->data;
  190.             while(bp->cnt--) {
  191.                 switch(*buf) {
  192.                     case '\012':    /* ignore LF */
  193.                     case '\032':    /* NO ^Z's! */
  194.                         break;
  195.                     case '\015':
  196.                         fputc('\015', stdout);
  197.                         fputc('\012', stdout);
  198.                         break;
  199.                     default:
  200.                         fputc(*buf, stdout);
  201.                         break;
  202.                 }
  203.                 buf++;
  204.             }
  205.             bp = free_mbuf(bp);
  206.         }
  207.     fflush(stdout);
  208. }
  209.  
  210. /* State change upcall routine */
  211. void
  212. f_state(tcb,old,new)
  213. register struct tcb    *tcb;
  214. char            old,        /* old state */
  215.             new;        /* new state */
  216. {
  217.     struct finger    *finger;
  218.     char        notify = 0;
  219.     extern char    *tcpstates[];
  220.     extern char    *reasons[];
  221.     extern char    *unreach[];
  222.     extern char    *exceed[];
  223.     struct mbuf    *bp;
  224.  
  225.     finger = (struct finger *)tcb->user;
  226.  
  227.     if(current != NULLSESSION && current->type == FINGER)
  228.         notify = 1;
  229.  
  230.     switch(new){
  231.  
  232.     case CLOSE_WAIT:
  233.         if(notify)
  234.             printf("%s\n",tcpstates[new]);
  235.         close_tcp(tcb);
  236.         break;
  237.  
  238.     case CLOSED:    /* finish up */
  239.         if(notify) {
  240.             printf("%s (%s", tcpstates[new], reasons[tcb->reason]);
  241.             if (tcb->reason == NETWORK){
  242.                 switch(tcb->type){
  243.                 case DEST_UNREACH:
  244.                     printf(": %s unreachable",unreach[tcb->code]);
  245.                     break;
  246.                 case TIME_EXCEED:
  247.                     printf(": %s time exceeded",exceed[tcb->code]);
  248.                     break;
  249.                 }
  250.             }
  251.             printf(")\n");
  252.             cmdmode();
  253.         }
  254.         if(finger != NULLFING)
  255.             free_finger(finger);
  256.         del_tcp(tcb);
  257.         break;
  258.     case ESTABLISHED:
  259.         if (notify) {
  260.             printf("%s\n",tcpstates[new]);
  261.         }
  262.         printf("[%s]\n", current->name);
  263.         bp = qdata(finger->user, (int16) strlen(finger->user));
  264.         send_tcp(tcb, bp);
  265.         break;
  266.         
  267.     default:
  268.         if(notify)
  269.             printf("%s\n",tcpstates[new]);
  270.         break;
  271.     }
  272.     fflush(stdout);
  273. }
  274.  
  275.  
  276.